package com.cloudptt.api.product.func.message;

import com.cloudptt.api.comm.CheckData;
import com.cloudptt.api.comm.CommDlg;
import com.cloudptt.api.comm.Common;
import com.cloudptt.api.pjsip.api.MessageInfo;
import com.cloudptt.api.pjsip.api.SipManager;
import com.cloudptt.api.product.func.IBroadcast;
import com.cloudptt.api.product.log.Log;
import com.cloudptt.api.product.operator.MsgOperator;
import com.hytera.productsdk.R;
import com.mcptt.config.body.InXml;
import com.mcptt.config.body.ResourceListsBody;
import com.mcptt.config.body.info.mcdata.McdataInfoBody;
import com.mcptt.config.body.info.mcdata.binary.PayloadBody;
import com.mcptt.config.body.info.mcdata.binary.SignalBody;
import com.mcptt.config.local.SysConfig;
import com.mcptt.db.DBAdapter;
import com.mcptt.db.model.AddrInfo;
import com.mcptt.db.model.SessionInfo;
import com.mcptt.db.model.SessionReadStatus;

import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.PowerManager;
import android.widget.Toast;

import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;

public class MsgBroadcast extends BroadcastReceiver implements IBroadcast
{
	private Context ctx = null;

	private NotifyListener notifyListener = null;
	private MsgListener msgListener = null;
	private AddrInfo curAddrInfo = null;
	private DBAdapter dbOperater = null;
	private MsgOperator op = null;
	private SysConfig config = null;
	private Class cls = null;
	private NotificationManagerCompat notificationManagerCompat = null;
	private NotificationManager notificationManager = null;

	public MsgBroadcast(Context ctx, DBAdapter dbOperater, MsgOperator op,SysConfig config)
	{
		Log.d(MsgFunc.Log_Key, "MsgBroadcast");
		this.ctx = ctx;
		this.dbOperater = dbOperater;
		this.op = op;
		this.config = config;
		this.notificationManagerCompat = NotificationManagerCompat.from(ctx);
		createNotificationChannel(ctx);
		this.ctx.registerReceiver(this, new IntentFilter(SipManager.ACTION_SIP_CALL_LOG));
		this.ctx.registerReceiver(this, new IntentFilter(SipManager.ACTION_SIP_MCDATA));
		this.ctx.registerReceiver(this, new IntentFilter(SipManager.ACTION_SIP_MCDATA_STATUS));
		this.ctx.registerReceiver(this, new IntentFilter(SipManager.ACTION_SIP_FD_FIND));
	}

	public void setMsgListener(MsgListener listener,AddrInfo curAddrInfo) {
		Log.d(MsgFunc.Log_Key, "setMsgListener listener = " + listener + " curAddrInfo = " + curAddrInfo);
		this.msgListener = listener;
		this.curAddrInfo = curAddrInfo;
	}

	public void setNotifyListener(NotifyListener listener) {
		this.notifyListener = listener;
	}

	public void setMsgSessionClass(Class cls)
	{
		Log.d(MsgFunc.Log_Key, "setMsgSessionClass cls = " + cls);
		this.cls = cls;
	}

	public void createNotificationChannel(Context context) {
		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
			String channelId = "message_channel";
			CharSequence name = "Messages";
			int importance = NotificationManager.IMPORTANCE_HIGH; // 高优先级
			NotificationChannel channel = new NotificationChannel(channelId, name, importance);
			channel.setDescription("Channel for message notifications");
			notificationManager = context.getSystemService(NotificationManager.class);
			notificationManager.createNotificationChannel(channel);
		}
	}

	@Override
	public void onReceive(Context context, Intent intent) {
		String action = intent.getAction();
		Log.d(MsgFunc.Log_Key, "Action is " + action);

		if(intent.getAction().equals(SipManager.ACTION_SIP_CALL_LOG)) //接受短消息广播
		{
			if(msgListener != null)
			{
				this.msgListener.receiveMsg();
			}
		}
		else if (SipManager.ACTION_SIP_FD_FIND.equals(action)) {
			try {
				String infoBodyStr = intent.getStringExtra(SipManager.Body_Str);
				Log.debug(this.getClass(), "onReceive: ACTION_SIP_FD_FIND infoBodyStr = " + infoBodyStr);
				McdataInfoBody infoBody = McdataInfoBody.parseXmlStr(infoBodyStr);
				Log.debug(this.getClass(), "onReceive: ACTION_SIP_FD_FIND infoBody = " + infoBody.toValString());
				if(infoBody != null) {
					String msgType = infoBody.getSessionType();
					if (msgType != null
							&& SessionInfo.MsgType_Desc_Msf_Disc_Res.equals(msgType)) {
						String url = infoBody.getControllerPsi();
						config.setFileSvrUrl(url);
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		else if(intent.getAction().equals(SipManager.ACTION_SIP_MCDATA)) //接受短消息广播
		{
			String mcdataInfoStr = intent.getStringExtra(SipManager.MSG_INFO_STR);
			Log.debug(this.getClass(), "ACTION_SIP_MESSAGE mcdataInfoStr = " + mcdataInfoStr);
			String signallingHexStr = intent.getStringExtra(SipManager.MSG_SIGNALLING_STR);
			Log.debug(this.getClass(), "ACTION_SIP_MESSAGE signallingHexStr.length() = " + signallingHexStr.length() + " signallingHexStr = " + signallingHexStr);
			if(mcdataInfoStr != null
					&& !mcdataInfoStr.trim().equals("")
					&& signallingHexStr != null
					&& !signallingHexStr.trim().equals(""))
			{
				McdataInfoBody info = McdataInfoBody.parseXmlStr(mcdataInfoStr);
				Log.debug(this.getClass(),  "ACTION_SIP_MESSAGE info = " + info.toValString());

				MessageInfo msgInfo = SignalBody.parsePayload(signallingHexStr);
				Log.debug(this.getClass(), "ACTION_SIP_MESSAGE msgInfo = " + msgInfo);
				if(info != null)
				{
					String url = info.getControllerPsi();
					msgInfo.setControllerPsi(url);
				}
				String resourceListStr = intent.getStringExtra(SipManager.MSG_RESOURCE_LIST);
				Log.debug(this.getClass(), "ACTION_SIP_MESSAGE resourceListStr = " + resourceListStr);
				if(info != null
						&& msgInfo != null) {
					String type = info.getSessionType();
					Log.debug(this.getClass(), "ACTION_SIP_MESSAGE type = " + type);
					if(msgInfo.isNtf())
					{
						String conversationId = msgInfo.getConversationId();
						String msgId = msgInfo.getMsgId();
						byte status = msgInfo.getStatus();
						procMcdataStatus(conversationId,msgId,status);
						if(!SessionInfo.isOtoMsg(type))
						{
							String temp = info.getPeerMcdataId();
							String groupId = AddrInfo.toNumFromSipUrl(temp);
							if(AddrInfo.isEmergencyNum(groupId))
							{
								groupId = "50299";
							}
							if(AddrInfo.isCall210(groupId))
							{
								groupId = "50210";
							}
							temp = info.getSendMcdataId();
							String addrId = AddrInfo.toNumFromSipUrl(temp);
							SessionReadStatus readStatus = new SessionReadStatus(conversationId,msgId,groupId,addrId,status);
							Log.debug(this.getClass(), "ACTION_SIP_MESSAGE readStatus = " + readStatus);
							dbOperater.addSessionReadStatus(readStatus);
						}
					}
					else if (SessionInfo.isFdMsg(type)
							&& msgInfo.isFd())
					{
						if (info != null
								&& msgInfo != null) {
							procFdMsg(info, msgInfo, resourceListStr);
						}
					}
					else if(msgInfo.isSds())
					{
						String payloadHexStr = intent.getStringExtra(SipManager.MSG_PAYLOAD_STR);
						Log.debug(this.getClass(), "ACTION_SIP_MESSAGE payloadHexStr = " + payloadHexStr);

						if (info != null
								&& payloadHexStr != null
								&& !payloadHexStr.equals("")
								&& msgInfo != null) {
							procSdsMsg(info, payloadHexStr, msgInfo, resourceListStr);
						}
					}
				}
			}
		}
		else if(intent.getAction().equals(SipManager.ACTION_SIP_MCDATA_STATUS)) //接受短消息广播
		{
			String idStr = intent.getStringExtra(SipManager.Body_IdStr);
			String inXmlStr = intent.getStringExtra(SipManager.Body_Str);
			Log.debug(this.getClass(), "ACTION_SIP_MCDATA_STATUS MsgType_Desc_Notify idStr = " + idStr + " inXmlStr = " + inXmlStr);
			InXml inXml = InXml.parseXmlStr(inXmlStr);
			Log.debug(this.getClass(), "onCallState inXml = " + inXml);
			if (inXml != null) {
				String errMsg = inXml.getMsg();
				String errSubMsg = inXml.getSubMsg();
				if(errMsg != null
						&& errMsg.length() > 0
						&& errSubMsg != null
						&& errSubMsg.length() > 0) {
					CommDlg.showToast(ctx, errMsg + errSubMsg);
				}
			}
			String[] strArr = idStr.split(":");
			if(strArr.length == 3) {
				String msgType = strArr[0];
				if(SessionInfo.MsgType_Desc_Notify.equals(msgType))
				{
					int statusCode = intent.getIntExtra(SipManager.Body_StatusCode, 0);
					Log.debug(this.getClass(), "ACTION_SIP_MCDATA_STATUS MsgType_Desc_Notify idStr = " + idStr + " statausCode = " + statusCode);
					//status = SessionInfo.Status_DELIVERED;
//					if (statusCode / 100 == 2) {
//						procMcdataStatus(strArr[1], strArr[2], SessionInfo.Status_SDS_READ);
//					}
				}
				else
				{
					int statusCode = intent.getIntExtra(SipManager.Body_StatusCode, 0);
					Log.debug(this.getClass(), "ACTION_SIP_MCDATA_STATUS other idStr = " + idStr + " statausCode = " + statusCode);
					int status = SessionInfo.Status_SDS_UNDELIVERED;
					if (statusCode / 100 == 2) {
						status = SessionInfo.Status_SDS_DELIVERED;
					}
					procMcdataStatus(strArr[1], strArr[2], status);
				}

			}
		}
	}

	private void procMcdataStatus(String conversationId,String msgId,int status)
	{
		Log.debug(this.getClass(), "procMcdataStatus conversationId = " + conversationId + " msgId = " + msgId + " status = " + status);
		dbOperater.updateSession(conversationId,msgId,status);
		if(msgListener != null)
		{
			this.msgListener.receiveMsg();
		}
	}

	private void procSdsMsg(McdataInfoBody info, String payloadStrHexStr, MessageInfo msgInfo, String resourceListStr)
	{
		try {
			Log.debug(this.getClass(), "procSdsMsg info = " + info + " msgInfo = " + msgInfo);
			String sessionType = info.getSessionType();

			msgInfo.setMsgType(sessionType);
			String peerMcdateId = info.getPeerMcdataId();
			String peerAddrId = AddrInfo.toNumFromSipUrl(peerMcdateId);

			String senderMcdateId = info.getSendMcdataId();
			String senderAddrId = AddrInfo.toNumFromSipUrl(senderMcdateId);


			PayloadBody payloadBody = PayloadBody.parsePayload(payloadStrHexStr);
			Log.debug(this.getClass(),  "procSdsMsg payloadBody = " + payloadBody.toString());
			int contentType = payloadBody.getType();
			msgInfo.setContentType(contentType);
			String content = payloadBody.getContent();
			msgInfo.setContent(content);

			if(resourceListStr != null
					&& !resourceListStr.equals(""))
			{
				ResourceListsBody body = ResourceListsBody.parseXmlStr(resourceListStr);
				Log.debug(this.getClass(),  "procSdsMsg body = " + body);
			}

			AddrInfo peerAddrInfo = null;
			AddrInfo sender = null;
			if(SessionInfo.isGroupMsg(sessionType))
			{
				peerAddrInfo = dbOperater.findGroupInfoByNum(peerAddrId);
			}
			else
			{
				peerAddrInfo = dbOperater.findUserInfoByNum(peerAddrId);
			}
			Log.d(MsgFunc.Log_Key, "procSdsMsg group peerAddrInfo = " + peerAddrInfo);
//			String sessionType = msgInfo.getMsgType();
//			if(!SessionInfo.isOtoMsg(sessionType))
//			{
			sender = dbOperater.findUserInfoByNum(senderAddrId);
//			}
//			else
//			{
//				sender = peerAddrInfo;
//			}
			Log.d(MsgFunc.Log_Key, "procSdsMsg sender = " + sender + " msgInfo = " + msgInfo);
			SessionInfo session  = new SessionInfo(peerAddrInfo,sender,msgInfo);
			Log.d(MsgFunc.Log_Key, "procSdsMsg session = " + session);
			this.dbOperater.insertNewSession(session,false);
			int dispositionReqType = msgInfo.getDispositionReqType();
			Log.d(MsgFunc.Log_Key, "procSdsMsg dispositionReqType = " + dispositionReqType);
			if(op != null
					&& (dispositionReqType & SessionInfo.DELIVERY) > 0) {
				op.sendNtfMessage(session, SessionInfo.Status_SDS_DELIVERED);
			}
			Log.d(MsgFunc.Log_Key, "procSdsMsg peerAddrInfo = " + peerAddrInfo + " curAddrInfo = " + curAddrInfo);
			if(curAddrInfo != null
					&& curAddrInfo.isSameOne(peerAddrInfo)) {
				if(op != null)
				{
					op.notification();
				}
			}
			else
			{
				sendNotification(ctx, session);
			}
			if(msgListener != null)
			{
				this.msgListener.receiveMsg();
			}
		}
		catch (Exception e)
		{
			e.printStackTrace();
			Log.debug(this.getClass(),  "procSdsMsg e = " + e);
		}

	}


	private void procFdMsg(McdataInfoBody info, MessageInfo msgInfo, String resourceListStr)
	{
		try {
			Log.debug(this.getClass(), "procFdMsg info = " + info + " msgInfo = " + msgInfo);
			String sessionType = info.getSessionType();
			msgInfo.setMsgType(sessionType);

			String peerMcdateId = info.getPeerMcdataId();
			Log.d(MsgFunc.Log_Key, "procFdMsg peerMcdateId = " + peerMcdateId);
			String peerAddrId = AddrInfo.toNumFromSipUrl(peerMcdateId);
			Log.d(MsgFunc.Log_Key, "procFdMsg 1 peerAddrId = " + peerAddrId);
			String senderMcdateId = info.getSendMcdataId();
			String senderAddrId = AddrInfo.toNumFromSipUrl(senderMcdateId);


			if(resourceListStr != null
					&& !resourceListStr.equals(""))
			{
				ResourceListsBody body = ResourceListsBody.parseXmlStr(resourceListStr);
				Log.debug(this.getClass(),  "procFdMsg body = " + body);
			}
			Log.d(MsgFunc.Log_Key, "procFdMsg peerAddrId = " + peerAddrId);
			AddrInfo peerAddrInfo = null;
			AddrInfo sender = null;
//			peerAddrInfo = dbOperater.findUserInfoByNum(peerAddrId);
//			if(peerAddrInfo == null)
//			{
//				peerAddrInfo  = dbOperater.findGroupInfoByNum(peerAddrId);
//			}
			if(SessionInfo.isGroupMsg(sessionType))
			{
				peerAddrInfo = dbOperater.findGroupInfoByNum(peerAddrId);

			}
			else
			{
				peerAddrInfo = dbOperater.findUserInfoByNum(peerAddrId);
			}
			Log.d(MsgFunc.Log_Key, "ACTION_SIP_MESSAGE group peerAddrInfo = " + peerAddrInfo);
			Log.d(MsgFunc.Log_Key, "procFdMsg fromAddrInfo = " + peerAddrInfo);
			sender = dbOperater.findUserInfoByNum(senderAddrId);
			Log.d(MsgFunc.Log_Key, "procFdMsg sender = " + sender);
			SessionInfo session  = new SessionInfo(peerAddrInfo,sender,msgInfo);
			this.dbOperater.insertNewSession(session,false);
			int dispositionReqType = msgInfo.getDispositionReqType();
			if(op != null
					&& (dispositionReqType & SessionInfo.DOWNLAOD) > 0) {
				op.sendNtfMessage(session, SessionInfo.Status_FD_REQUEST_ACCEPTED);
			}
			Log.d(MsgFunc.Log_Key, "procFdMsg peerAddrInfo = " + peerAddrInfo + " curAddrInfo = " + curAddrInfo);
			if(curAddrInfo != null
					&& curAddrInfo.isSameOne(peerAddrInfo))
			{
				if(op != null)
				{
					op.notification();
				}
			}
			else
			{
				sendNotification(ctx, session);
			}
			if(msgListener != null)
			{
				this.msgListener.receiveMsg();
			}
		}
		catch (Exception e)
		{
			e.printStackTrace();
			Log.debug(this.getClass(),  "procDataMsg e = " + e);
		}
	}


	public void sendNotification(Context context, SessionInfo session) {

		AddrInfo peerAddrInfo = session.getPeerAddrInfo();
		Log.debug(this.getClass(),  "sendNotification peerAddrInfo = " + peerAddrInfo);
		String title = peerAddrInfo.getDscp();
		String content = session.getContentDesc();

		NotificationCompat.Builder builder = new NotificationCompat.Builder(context, "message_channel")
				.setSmallIcon(R.drawable.ptticon)
				.setContentTitle(title)
				.setContentText(content)
				.setPriority(NotificationCompat.PRIORITY_HIGH) // 关键：高优先级触发亮屏
				.setAutoCancel(true);

		notificationManager.cancelAll();

		int requestCode = (int) System.currentTimeMillis();
		if(cls != null)
		{
			Intent intent = new Intent(ctx, cls);
			intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
			intent.putExtra("session", peerAddrInfo);
			Log.debug(this.getClass(),  "sendNotification cls peerAddrInfo = " + peerAddrInfo);
			PendingIntent pendingIntent = PendingIntent.getActivity(
					context, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
			);
			builder.setContentIntent(pendingIntent);
		}
		notificationManagerCompat.notify(requestCode, builder.build());
//		wakeScreen(context); // 调用唤醒屏幕方法\
		requestWakeLock(10);
	}

//	private boolean isAppRunning() {
//		// 获取当前运行的应用程序列表
//		ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
//		// 获取当前应用程序的包名
//		List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
//		if (appProcesses == null) {
//			return false;
//		}
//		// 遍历应用程序列表，检查当前应用程序是否在运行中
//		final String packageName = getPackageName();
//		for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
//			if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND &&
//					appProcess.processName.equals(packageName)) {
//				return true;
//			}
//		}
//		return false;
//	}


	public void requestWakeLock(long sec) {
		Log.debug(this.getClass(), "requestWakeLock sec = " + sec);
		PowerManager powerManager = (PowerManager) ctx.getSystemService(Context.POWER_SERVICE);
		if (powerManager != null) {
			boolean screenOn = powerManager.isScreenOn();
			Log.debug(this.getClass(), "requestWakeLock screenOn = " + screenOn);
			if(!screenOn) {
				PowerManager.WakeLock wakeLock = powerManager.newWakeLock(
						PowerManager.SCREEN_BRIGHT_WAKE_LOCK | // 全亮屏模式
								PowerManager.ACQUIRE_CAUSES_WAKEUP, // 强制唤醒
						"msg"
				);
				wakeLock.acquire(sec * 1000L); // 亮屏10秒后自动释放，避免耗电
				wakeLock.release(); // 立即释放锁
			}
		}
	}
	public void clearResource()
	{
		Log.d(MsgFunc.Log_Key, "MsgBroadcast clearResource");
		this.ctx.unregisterReceiver(this);
		this.ctx = null;
		this.msgListener = null;
	}
}
